/*
 * vws_logger.h
 *
 *  Created on: Sep 20, 2013
 *      Author: vscen
 */

#ifndef VWS_LOGGER_H_
#define VWS_LOGGER_H_

#include "vws_config.h"

namespace vws {
namespace vws_logger_const {
const int kDbgError = 0;
const int kDbgWarn = 1;
const int kDbgDebug = 2;
}
class vws_logger {
	/**
	 * \brief Type used for the configuration
	 */
	enum loggerConf_ {
		L_nofile_ = 1 << 0,
		L_file_ = 1 << 1,
		L_noscreen_ = 1 << 2,
		L_screen_ = 1 << 3
	};

	/**
	 * \brief Lock for mutual exclusion between different threads
	 */
	static pthread_mutex_t lock_;

	bool configured_;

	/**
	 * \brief Pointer to the unique Logger (i.e., Singleton)
	 */
	static vws_logger* m_;

	/**
	 * \brief Initial part of the name of the file used for Logging.
	 * Date and time are automatically appended.
	 */
	std::string logFile_;

	/**
	 * \brief Current configuration of the logger.
	 * Variable to know if logging on file and on screen are enabled.
	 * Note that if the log on file is enabled, it means that the
	 * logger has been already configured, therefore the stream is
	 * already open.
	 */
	loggerConf_ configuration_;

	/**
	 * \brief Stream used when logging on a file
	 */
	std::ofstream out_;

	/**
	 * \brief Initial time (used to print relative times)
	 */
	struct timeval initialTime_;

	/**
	 * \brief Verbosity threshold for files
	 */
	unsigned int fileVerbosityLevel_;

	/**
	 * \brief Verbosity threshold for screen
	 */
	unsigned int screenVerbosityLevel_;

	vws_logger();
	~vws_logger();

	/**
	 * \brief Method to lock in case of multithreading
	 */
	inline static void lock();

	/**
	 * \brief Method to unlock in case of multithreading
	 */
	inline static void unlock();

public:

	typedef loggerConf_ loggerConf;
	static const loggerConf file_on = L_nofile_;
	static const loggerConf file_off = L_file_;
	static const loggerConf screen_on = L_noscreen_;
	static const loggerConf screen_off = L_screen_;

	static vws_logger& getInstance();

	void print(const unsigned int verbosityLevel,
			const std::string& sourceFile, const int codeLine,
			const std::string& message);

	void configure(const std::string& outputFile,
			const loggerConf configuration, const int fileVerbosityLevel,
			const int screenVerbosityLevel);
private:
	DISALLOW_COPY_AND_ASSIGN(vws_logger);
};
}

#endif /* VWS_LOGGER_H_ */
